module top (
    input clk,
    input rst,
    input [15:0] sw,
    input ps2_clk,
    input ps2_data,
    input [4:0] button,
    output [15:0] ledr,
    output VGA_CLK,
    output VGA_HSYNC,
    output VGA_VSYNC,
    output VGA_BLANK_N,
    output [7:0] VGA_R,
    output [7:0] VGA_G,
    output [7:0] VGA_B,
    output [7:0] seg0,
    output [7:0] seg1,
    output [7:0] seg2,
    output [7:0] seg3,
    output [7:0] seg4,
    output [7:0] seg5,
    output [7:0] seg6,
    output [7:0] seg7
);

/*led led1(
    .clk(clk),
    .rst(rst),
    .sw(sw),
    .ledr(ledr)
);
*/
// 41选择器
/*smux41 mux41_1(
    .a(sw[9:2]),
    .s(sw[1:0]),
    .y(ledr[1:0])
);*/

// ps2
wire [7:0] ascii, ascii_lower;
wire [7:0] num;
wire [7:0] data;
wire ready,overflow;
wire nextdata_n, up, capslock;
reg [7:0] fifo[3:0];
reg [1:0] wptr;
ram ram_1(
    .code(fifo[wptr-2'b1]),
    .ascii(ascii_lower)
);
assign ledr[15] = capslock;
assign ascii = (capslock & ascii_lower>='h61 & ascii_lower<='h7a)? ascii_lower-'h20: ascii_lower;
// 高两位显示计数
/*counter counter_1(
    .clk(up),
    .out_q(num)
);*/
ps2_keyboard_fifo my_keyboard(
    .clk(clk),
    .clrn(~rst),
    .ps2_clk(ps2_clk),
    .ps2_data(ps2_data),
    .data(data),
    .ready(ready),
    .nextdata_n(nextdata_n),
    .overflow(overflow)
);
// 处理FIFO内容，根据断码F0返回按键松开信息
ps2_keyboard_handle keyboard_test(
    .clk(clk),
    .clrn(~rst),
    .data(data),
    .ready(ready),
    .overflow(overflow),
    .nextdata_n(nextdata_n),
    .fifo(fifo),
    .wptr(wptr),
    .up(up),
    .state(ledr[5:4]),
    .next_state(ledr[3:2]),
    .count(num),
    .CapsLock(capslock)
);
bcd7seg bcd7seg_0(
  .b(fifo[wptr-2'b1][3:0]),
  .en(1'b1),
  .h(seg0[7:1])
);
bcd7seg bcd7seg_1(
  .b(fifo[wptr-2'b1][7:4]),
  .en(1'b1),
  .h(seg1[7:1])
);
bcd7seg bcd7seg_2(
  .b(fifo[wptr-2'b10][3:0]),
  .en(1'b1),
  .h(seg2[7:1])
);
bcd7seg bcd7seg_3(
  .b(fifo[wptr-2'b10][7:4]),
  .en(1'b1),
  .h(seg3[7:1])
);
bcd7seg bcd7seg_4(
  .b(ascii[3:0]),
  .en(1'b1),
  .h(seg4[7:1])
);
bcd7seg bcd7seg_5(
  .b(ascii[7:4]),
  .en(1'b1),
  .h(seg5[7:1])
);
bcd7seg bcd7seg_6(
  .b(num[3:0]),
  .en(1'b1),
  .h(seg6[7:1])
);
bcd7seg bcd7seg_7(
  .b(num[7:4]),
  .en(1'b1),
  .h(seg7[7:1])
);
assign ledr[1:0] = {overflow, ready};
assign ledr[9:8] = {nextdata_n, up};
// 
assign VGA_CLK = clk;

wire [9:0] h_addr;
wire [9:0] v_addr;
wire [23:0] vga_data;

vga_ctrl my_vga_ctrl(
    .pclk(clk),
    .reset(rst),
    .vga_data(vga_data),
    .h_addr(h_addr),
    .v_addr(v_addr),
    .hsync(VGA_HSYNC),
    .vsync(VGA_VSYNC),
    .valid(VGA_BLANK_N),
    .vga_r(VGA_R),
    .vga_g(VGA_G),
    .vga_b(VGA_B)
);

/*ps2_keyboard my_keyboard(
    .clk(clk),
    .resetn(~rst),
    .ps2_clk(ps2_clk),
    .ps2_data(ps2_data)
);*/

/*seg mu_seg(
    .clk(clk),
    .rst(rst),
    .o_seg0(seg0),
    .o_seg1(seg1),
    .o_seg2(seg2),
    .o_seg3(seg3),
    .o_seg4(seg4),
    .o_seg5(seg5),
    .o_seg6(seg6),
    .o_seg7(seg7)
);*/

vmem my_vmem(
    .h_addr(h_addr),
    .v_addr(v_addr[8:0]),
    .vga_data(vga_data)
);

endmodule

module vmem (
    input [9:0] h_addr,
    input [8:0] v_addr,
    output [23:0] vga_data
);

reg [23:0] vga_mem [524287:0];

initial begin
    $readmemh("resource/picture.hex", vga_mem);
end

assign vga_data = vga_mem[{h_addr, v_addr}];

endmodule

module ram (
    input [7:0] code,
    output [7:0] ascii
);
    reg [7:0] ram[127:0];
initial begin
    $readmemh("resource/scanasciilower.txt", ram, 0, 127);
end
    assign ascii = ram[code[6:0]];
endmodule


